package com.rkc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rkc.enums.BizCodeEnum;
import com.rkc.enums.SendCodeEnum;
import com.rkc.feign.CouponFeignService;
import com.rkc.interceptor.LoginInterceptor;
import com.rkc.mapper.UserMapper;
import com.rkc.model.LoginUser;
import com.rkc.model.UserDO;
import com.rkc.request.NewUserCouponRequest;
import com.rkc.request.UserLoginRequest;
import com.rkc.request.UserRegisterRequest;
import com.rkc.service.NotifyService;
import com.rkc.service.UserService;
import com.rkc.utils.CommonUtil;
import com.rkc.utils.JsonData;
import com.rkc.utils.JwtUtil;
import com.rkc.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author `RKC`
 * @date 2021/10/16 14:55
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private NotifyService notifyService;

    @Resource
    private UserMapper userMapper;

    @Autowired
    private CouponFeignService couponFeignService;

    /**
     * 用户注册
     * - 邮箱验证码验证
     * - 密码加密
     * - 账号唯一性检查
     * - 插入数据库
     * - 新注册用户福利发放
     * @param registerRequest
     * @return
     */
//    @GlobalTransactional
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public JsonData register(UserRegisterRequest registerRequest) {
        //验证码校验
        if (StringUtils.isBlank(registerRequest.getMail()) || !notifyService.checkCode(SendCodeEnum.USER_REGISTER,
                registerRequest.getMail(), registerRequest.getCode())) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(registerRequest, userDO);
        userDO.setCreateTime(new Date());
        userDO.setSlogan("人生需要动态规划，学习需要贪心算法");
        //密码加密
        //生成秘钥，盐
        userDO.setSecret("$1$" + CommonUtil.getStringNumRandom(8));
        //密码+盐处理
        String cryptPwd = Md5Crypt.md5Crypt(registerRequest.getPwd().getBytes(), userDO.getSecret());
        userDO.setPwd(cryptPwd);

        int row = userMapper.insert(userDO);
        log.info("row: {}, 注册成功：{}", row, userDO);
        //新用户注册成功，初始化信息，发放福利
        userTaskAfterRegister(userDO);
        return JsonData.buildSuccess();
    }

    /**
     * 根据mail查找记录，如果存在则用秘钥+明文密码进行加密后与数据库的密文进行对比
     * @param loginRequest
     * @return
     */
    @Override
    public JsonData login(UserLoginRequest loginRequest) {
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("mail", loginRequest.getMail()));
        if (userDO == null) {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }
        String cryptPwd = Md5Crypt.md5Crypt(loginRequest.getPwd().getBytes(), userDO.getSecret());
        if (cryptPwd.equals(userDO.getPwd())) {
            LoginUser loginUser = new LoginUser();
            BeanUtils.copyProperties(userDO, loginUser);
            //生成token
            String token = JwtUtil.generateJsonWebToken(loginUser);
            return JsonData.buildSuccess(token);
        }
        return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
    }

    @Override
    public UserVO findUserDetail() {
        LoginUser loginUser = LoginInterceptor.THREAD_LOCAL.get();
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userDO, userVO);
        return userVO;
    }

    /**
     * 注册成功后的初始化逻辑
     * @param userDO
     */
    private void userTaskAfterRegister(UserDO userDO) {
        NewUserCouponRequest newUserCouponRequest = new NewUserCouponRequest();
        newUserCouponRequest.setUserId(userDO.getId());
        newUserCouponRequest.setName(userDO.getName());
        couponFeignService.addNewUserCoupon(newUserCouponRequest);
//        JsonData result = couponFeignService.addNewUserCoupon(newUserCouponRequest);
        //鉴于全局异常处理器的原因，可以根据服务调用返回的状态码进行手动抛出异常，以便全局事务回滚
//        if (result.getCode() != 0) {
//            throw new RuntimeException("发放优惠券异常");
//        }
    }
}
